package com.lds.erp.util;

import java.io.Serializable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.dph.common.utils.base.ToString;
import com.dph.common.utils.service.Base;
import com.dph.common.utils.service.BaseResult;
import com.lds.erp.base.JsonResult;

/**
 * @author hongsir
 * @apiNote
 * @date 2018/9/29 上午9:18
 */
public class JsonUtils implements Serializable {
    private static final long serialVersionUID = 7940850696134948235L;
    private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);
    private static final String DEFAULT_SUCCESS_CODE = "1";
    private static final String DEFAULT_FAIL_CODE = "0";
    private static final String DEFAULT_SUCCESS_MESSAGE = "操作成功";
    private static final String DEFAULT_FAIL_MESSAGE = "操作失败";
    private static final String DEFAULT_EXCEPTION_MESSAGE = "服务器繁忙，请稍后重试";

    /**
     * 直接透传所有继承了BaseResult的结果集
     * 失败返回失败信息
     * 成功返回数据+信息
     *
     * @param result
     * @param voClazz
     * @param <VO>
     * @param <Result>
     * @return
     */
    public static <VO extends Base, Result extends BaseResult> JsonResult<VO> result(Result result, Class<VO> voClazz) {
        if (result.isSuccess()) {
            if (null != voClazz) {
                String dataJson = JSON.toJSONString(result);
                VO vo = JSON.parseObject(dataJson, voClazz);
                return success(result.getMessage(), vo);
            } else {
                return success(result.getMessage());
            }

        } else {
            return fail(result.getMessage());
        }
    }

    public static <VO extends Base, Result extends BaseResult> JsonResult<VO> result(Result result) {
        return result(result, null);
    }

    /**
     * @param result  业务返回对象
     * @param voClazz 返回类型
     * @param <VO>    与 <Result> 的属性值必须保持一致,属性对象可以不是同一个,但是对应的属性名必须一致
     *                举例:
     *                Result: private PageEntity<A> pageInfo;
     *                VO: private PageVO<B> pageInfo;
     *                其中的pageInfo保持一致,A和B中的属性名也必须保持一致,就可以实现属性转换了
     * @return T
     */
    public static <VO extends Base, Result extends BaseResult> JsonResult<VO> success(Result result, Class<VO> voClazz) {
        String dataJson = JSON.toJSONString(result);
        VO vo = JSON.parseObject(dataJson, voClazz);
        return success(vo);
    }


    public static <VO extends Base, Result extends BaseResult> JsonResult<VO> fail(Result result, Class<VO> voClazz) {
        String dataJson = JSON.toJSONString(result);
        VO vo = JSON.parseObject(dataJson, voClazz);
        return fail(result.getMessage(),vo);
    }

    public static <VO> JsonResult<VO> success() {
        return newJsonResult(true, DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, null);
    }

    public static <VO> JsonResult<VO> success(String code, String message, VO vo) {
        return newJsonResult(true, code, message, vo);
    }

    public static <VO> JsonResult<VO> success(String message, VO vo) {
        return success(DEFAULT_SUCCESS_CODE, message, vo);
    }

    public static <VO> JsonResult<VO> success(String message) {
        return success(DEFAULT_SUCCESS_CODE, message, null);
    }

    public static <VO> JsonResult<VO> success(VO vo) {
        return success(DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, vo);
    }


    public static <VO> JsonResult<VO> fail(String code, String message, VO vo) {
        return newJsonResult(false, code, message, vo);
    }

    public static <VO> JsonResult<VO> fail(String message, VO vo) {
        return fail(DEFAULT_FAIL_CODE, message, vo);
    }

    public static <VO> JsonResult<VO> fail(String message) {
        return fail(DEFAULT_FAIL_CODE, message, null);
    }

    public static <VO> JsonResult<VO> fail(VO vo) {
        return fail(DEFAULT_FAIL_CODE, DEFAULT_FAIL_MESSAGE, vo);
    }

    /**
     * 实例化一个自定义的json对象
     *
     * @param success 业务处理状态
     * @param code    返回码
     * @param message 返回信息
     * @param vo      返回数据
     * @param <VO>    数据包含的泛型
     * @return 自定义的json对象
     */
    private static <VO> JsonResult<VO> newJsonResult(boolean success, String code, String message, VO vo) {
        if (hasException(message) && !success) {
            log.info("Ajax请求应答>>>状态：{}，code：{}，message：{}，data：{}", success, code, message, vo);
            message = DEFAULT_EXCEPTION_MESSAGE;
        }
        log.info("Ajax请求应答>>>状态：{}，code：{}，message：{}，data：{}", success, code, message, vo);
        return new JsonResult<>(success, code, message, vo);
    }

    /**
     * 是否有异常消息
     *
     * @param message
     * @return
     */
    public static boolean hasException(String message) {
        return StringUtils.hasText(message) && message.contains("Exception");
    }

    @Override
    public String toString() {
        return ToString.toString(this);
    }
}